 /*******************************************************************************
  * Copyright (c) 2000, 2007 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
  *
  * Contributors:
  * IBM Corporation - initial API and implementation
  * Dan Rubel <dan_rubel@instantiations.com>
  * - Fix for bug 11490 - define hidden view (placeholder for view) in plugin.xml
  * Ted Stockwell <emorning@yahoo.com>
  * - Fix for bug 63595 - IPageLayout.addFastView regression (3.0M8 to 3.0M9)
  * Chris Gross <schtoo@schtoo.com>
  * - Fix for 99155 - allow standalone view placeholders
  * Chris Gross chris.gross@us.ibm.com Bug 107443
  *******************************************************************************/
 package org.eclipse.ui.internal;

 import java.util.ArrayList ;
 import java.util.HashMap ;
 import java.util.List ;
 import java.util.Map ;

 import org.eclipse.osgi.util.NLS;
 import org.eclipse.swt.SWT;
 import org.eclipse.ui.IFolderLayout;
 import org.eclipse.ui.IPageLayout;
 import org.eclipse.ui.IPerspectiveDescriptor;
 import org.eclipse.ui.IPlaceholderFolderLayout;
 import org.eclipse.ui.IViewLayout;
 import org.eclipse.ui.IViewReference;
 import org.eclipse.ui.PartInitException;
 import org.eclipse.ui.activities.WorkbenchActivityHelper;
 import org.eclipse.ui.internal.presentations.PresentationFactoryUtil;
 import org.eclipse.ui.internal.registry.ActionSetRegistry;
 import org.eclipse.ui.internal.registry.IActionSetDescriptor;
 import org.eclipse.ui.views.IViewDescriptor;
 import org.eclipse.ui.views.IViewRegistry;

 /**
  * This factory is used to define the initial layout of a part sash container.
  * <p>
  * Design notes: The design of <code>IPageLayout</code> is a reflection of
  * three requirements:
  * <ol>
  * <li>A mechanism is required to define the initial layout for a page. </li>
  * <li>The views and editors within a page will be persisted between
  * sessions.</li>
  * <li>The view and editor lifecycle for (1) and (2) should be identical.</li>
  * </ol>
  * </p>
  * <p>
  * In reflection of these requirements, the following strategy has been
  * implemented for layout definition.
  * <ol>
  * <li>A view extension is added to the workbench registry for the view.
  * This extension defines the extension id and extension class. </li>
  * <li>A view is added to a page by invoking one of the add methods
  * in <code>IPageLayout</code>. The type of view is passed as an
  * extension id, rather than a handle. The page layout will map
  * the extension id to a view class, create an instance of the class,
  * and then add the view to the page.</li>
  * </ol>
  * </p>
  */
 public class PageLayout implements IPageLayout {
     private ArrayList actionSets = new ArrayList (3);

     private IPerspectiveDescriptor descriptor;

     private LayoutPart editorFolder;

     private boolean editorVisible = true;

     private boolean fixed;

     private ArrayList fastViews = new ArrayList (3);

     private Map mapIDtoFolder = new HashMap (10);

     private Map mapIDtoPart = new HashMap (10);

     private Map mapIDtoViewLayoutRec = new HashMap (10);
     
     private Map mapFolderToFolderLayout = new HashMap (10);

     private ArrayList newWizardShortcuts = new ArrayList (3);

     private ArrayList perspectiveShortcuts = new ArrayList (3);

     private ViewSashContainer rootLayoutContainer;

     private ArrayList showInPartIds = new ArrayList (3);

     private ArrayList showViewShortcuts = new ArrayList (3);

     private ViewFactory viewFactory;

     private List minimizedStacks = new ArrayList ();

     /**
      * Constructs a new PageLayout for other purposes.
      */
     public PageLayout() {
         //no-op
 }

     /**
      * Constructs a new PageLayout for the normal case of creating a new
      * perspective.
      */
     public PageLayout(ViewSashContainer container, ViewFactory viewFactory,
             LayoutPart editorFolder, IPerspectiveDescriptor descriptor) {
         super();
         this.viewFactory = viewFactory;
         this.rootLayoutContainer = container;
         this.editorFolder = editorFolder;
         this.descriptor = descriptor;
         prefill();
     }

     /**
      * Adds the editor to a layout.
      */
     private void addEditorArea() {
         try {
             // Create the part.
 LayoutPart newPart = createView(ID_EDITOR_AREA);
             if (newPart == null) {
                 // this should never happen as long as newID is the editor ID.
 return;
             }

             setRefPart(ID_EDITOR_AREA, newPart);

             // Add it to the layout.
 rootLayoutContainer.add(newPart);
         } catch (PartInitException e) {
             WorkbenchPlugin.log(getClass(), "addEditorArea()", e); //$NON-NLS-1$
 }
     }

     /**
      * Adds an action set to the page.
      *
      * @param actionSetID Identifies the action set extension to use. It must
      * exist within the workbench registry.
      */
     public void addActionSet(String actionSetID) {
         if (!actionSets.contains(actionSetID)) {
             actionSets.add(actionSetID);
         }
     }

     /* (non-Javadoc)
      * @see org.eclipse.ui.IPageLayout#addFastView(java.lang.String)
      */
     public void addFastView(String id) {
         addFastView(id, INVALID_RATIO);
     }

     /* (non-Javadoc)
      * @see org.eclipse.ui.IPageLayout#addFastView(java.lang.String, float)
      */
     public void addFastView(String id, float ratio) {
         if (checkPartInLayout(id)) {
             return;
         }
         if (id != null) {
             try {
                 IViewDescriptor viewDescriptor = viewFactory.getViewRegistry()
                         .find(ViewFactory.extractPrimaryId(id));
                 if (!WorkbenchActivityHelper.filterItem(viewDescriptor)) {
                     IViewReference ref = viewFactory.createView(ViewFactory
                             .extractPrimaryId(id), ViewFactory
                             .extractSecondaryId(id));
                     fastViews.add(ref);

                     // force creation of the view layout rec
 ViewLayoutRec rec = getViewLayoutRec(id, true);

                     // remember the ratio, if valid
 if (ratio >= IPageLayout.RATIO_MIN
                             && ratio <= IPageLayout.RATIO_MAX) {
                         rec.fastViewWidthRatio = ratio;
                     }
                 }
             } catch (PartInitException e) {
                 WorkbenchPlugin.log(getClass(), "addFastView", e); //$NON-NLS-1$
 }
         }
     }

     /**
      * Check to see if the partId represents a fast view's id.
      *
      * @param partId
      * The part's id.
      * @return true if the partId is a fast view id.
      */
     private boolean isFastViewId(String partId) {
         for (int i = 0; i < fastViews.size(); i++) {
             IViewReference ref = (IViewReference) fastViews.get(i);
             String secondaryId = ref.getSecondaryId();
             String refId = (secondaryId == null ? ref.getId() : ref.getId()
                     + ":" + secondaryId); //$NON-NLS-1$
 if (refId.equals(partId)) {
                 return true;
             }
         }
         return false;
     }

     /**
      * Returns the view layout record for the given view id, or null if not
      * found. If create is true, the record is created if it doesn't already
      * exist.
      *
      * @since 3.0
      */
     ViewLayoutRec getViewLayoutRec(String id, boolean create) {
         ViewLayoutRec rec = (ViewLayoutRec) mapIDtoViewLayoutRec.get(id);
         if (rec == null && create) {
             rec = new ViewLayoutRec();
             // set up the view layout appropriately if the page layout is fixed
 if (isFixed()) {
                 rec.isCloseable = false;
                 rec.isMoveable = false;
             }
             mapIDtoViewLayoutRec.put(id, rec);
         }
         return rec;
     }

     /**
      * Adds a creation wizard to the File New menu.
      * The id must name a new wizard extension contributed to the
      * workbench's extension point (named <code>"org.eclipse.ui.newWizards"</code>).
      *
      * @param id the wizard id
      */
     public void addNewWizardShortcut(String id) {
         if (!newWizardShortcuts.contains(id)) {
             newWizardShortcuts.add(id);
         }
     }

     /**
      * Add the layout part to the page's layout
      */
     private void addPart(LayoutPart newPart, String partId, int relationship,
             float ratio, String refId) {

         setRefPart(partId, newPart);

         // If the referenced part is inside a folder,
 // then use the folder as the reference part.
 LayoutPart refPart = getFolderPart(refId);
         if (refPart == null) {
             refPart = getRefPart(refId);
         }

         // Add it to the layout.
 if (refPart != null) {
             ratio = normalizeRatio(ratio);
             rootLayoutContainer.add(newPart, getPartSashConst(relationship),
                     ratio, refPart);
         } else {
             WorkbenchPlugin.log(NLS.bind(WorkbenchMessages.PageLayout_missingRefPart, refId ));
             rootLayoutContainer.add(newPart);
         }
     }

     /**
      * Adds a perspective shortcut to the Perspective menu.
      * The id must name a perspective extension contributed to the
      * workbench's extension point (named <code>"org.eclipse.ui.perspectives"</code>).
      *
      * @param id the perspective id
      */
     public void addPerspectiveShortcut(String id) {
         if (!perspectiveShortcuts.contains(id)) {
             perspectiveShortcuts.add(id);
         }
     }

     /* (non-Javadoc)
      * @see org.eclipse.ui.IPageLayout#addPlaceholder(java.lang.String, int, float, java.lang.String)
      */
     public void addPlaceholder(String viewId, int relationship, float ratio,
             String refId) {
         if (!checkValidPlaceholderId(viewId)) {
             return;
         }

         // Create the placeholder.
 PartPlaceholder newPart = new PartPlaceholder(viewId);
         addPart(newPart, viewId, relationship, ratio, refId);
         // force creation of the view layout rec
 getViewLayoutRec(viewId, true);
     }

     /**
      * Checks whether the given id is a valid placeholder id.
      * A placeholder id may be simple or compound, and can optionally contain a wildcard.
      *
      * @param id the placeholder id
      * @return <code>true</code> if the given id is a valid placeholder id, <code>false</code> otherwise
      */
     boolean checkValidPlaceholderId(String id) {
         // Check that view is not already in layout.
 // This check is done even if the id has a wildcard, since it's incorrect to create
 // multiple placeholders with the same id, wildcard or not.
 if (checkPartInLayout(id)) {
             return false;
         }

         // check that primary view id is valid, but only if it has no wildcard
 String primaryId = ViewFactory.extractPrimaryId(id);
         if (!ViewFactory.hasWildcard(primaryId)) {
             IViewRegistry reg = WorkbenchPlugin.getDefault().getViewRegistry();
             IViewDescriptor desc = reg.find(primaryId);
             if (desc == null) {
                 // cannot safely open the dialog so log the problem
 WorkbenchPlugin.log("Unable to find view with id: " + primaryId + ", when creating perspective " + getDescriptor().getId()); //$NON-NLS-1$ //$NON-NLS-2$
 return false;
             }
         }

         return true;
     }

     /* (non-Javadoc)
      * @see org.eclipse.ui.IPageLayout#addShowInPart(java.lang.String)
      */
     public void addShowInPart(String id) {
         if (!showInPartIds.contains(id)) {
             showInPartIds.add(id);
         }
     }

     /**
      * Adds a view to the Show View menu. The id must name a view extension
      * contributed to the workbench's extension point (named <code>"org.eclipse.ui.views"</code>).
      *
      * @param id the view id
      */
     public void addShowViewShortcut(String id) {
         if (!showViewShortcuts.contains(id)) {
             showViewShortcuts.add(id);
         }
     }

     /* (non-Javadoc)
      * @see org.eclipse.ui.IPageLayout#addView(java.lang.String, int, float, java.lang.String)
      */
     public void addView(String viewId, int relationship, float ratio,
             String refId) {
         addView(viewId, relationship, ratio, refId, false, false, true);
     }

     /**
      * Convenience method to allow setting the initial minimized
      * state if a new stack is created. Used by the 'perspectiveExtension'
      * reader.
      *
      * @since 3.3
      */
     public void addView(String viewId, int relationship, float ratio,
             String refId, boolean minimized) {
         addView(viewId, relationship, ratio, refId, minimized, false, true);
     }

     /* (non-Javadoc)
      * @see org.eclipse.ui.IPageLayout#addView(java.lang.String, int, float, java.lang.String)
      */
     private void addView(String viewId, int relationship, float ratio,
             String refId, boolean minimized, boolean standalone, boolean showTitle) {
         if (checkPartInLayout(viewId)) {
             return;
         }

         try {
             // Create the part.
 LayoutPart newPart = createView(viewId);
             if (newPart == null) {
                 addPlaceholder(viewId, relationship, ratio, refId);
                 LayoutHelper.addViewActivator(this, viewId);
             } else {
                 int appearance = PresentationFactoryUtil.ROLE_VIEW;
                 if (standalone) {
                     if (showTitle) {
                         appearance = PresentationFactoryUtil.ROLE_STANDALONE;
                     } else {
                         appearance = PresentationFactoryUtil.ROLE_STANDALONE_NOTITLE;
                     }
                 }

                 ViewStack newFolder = new ViewStack(rootLayoutContainer.page,
                         true, appearance, null);
                 newFolder.add(newPart);
                 setFolderPart(viewId, newFolder);
                 addPart(newFolder, viewId, relationship, ratio, refId);
                 // force creation of the view layout rec
 getViewLayoutRec(viewId, true);
                 
                 // Capture any minimized stacks
 if (minimized) {
                     // Remember the minimized stacks so we can
 // move them to the trim when the Perspective
 // activates...
 minimizedStacks.add(newFolder);
                 }
             }
         } catch (PartInitException e) {
             WorkbenchPlugin.log(getClass(), "addView", e); //$NON-NLS-1$
 }
     }

     public List getMinimizedStacks() {
         return minimizedStacks;
     }
     
     /**
      * Verify that the part is already present in the layout
      * and cannot be added again. Log a warning message.
      */
     /*package*/
     boolean checkPartInLayout(String partId) {
         if (getRefPart(partId) != null || isFastViewId(partId)) {
             WorkbenchPlugin.log(NLS.bind(WorkbenchMessages.PageLayout_duplicateRefPart,partId ));
             return true;
         }

         return false;
     }

     /* (non-Javadoc)
      * @see org.eclipse.ui.IPageLayout#createFolder(java.lang.String, int, float, java.lang.String)
      */
     public IFolderLayout createFolder(String folderId, int relationship,
             float ratio, String refId) {
         if (checkPartInLayout(folderId)) {
             ViewStack folder = (ViewStack) getRefPart(folderId);
             
             return (IFolderLayout) mapFolderToFolderLayout.get(folder);
         }

         // Create the folder.
 ViewStack folder = new ViewStack(rootLayoutContainer.page);
         folder.setID(folderId);
         addPart(folder, folderId, relationship, ratio, refId);

         // Create a wrapper.
 FolderLayout layout = new FolderLayout(this, folder, viewFactory);
         
         mapFolderToFolderLayout.put(folder,layout);
         
         return layout;
     }

     /* (non-Javadoc)
      * @see org.eclipse.ui.IPageLayout#createPlaceholderFolder(java.lang.String, int, float, java.lang.String)
      */
     public IPlaceholderFolderLayout createPlaceholderFolder(String folderId,
             int relationship, float ratio, String refId) {
         if (checkPartInLayout(folderId)) {
             ContainerPlaceholder folder = (ContainerPlaceholder) getRefPart(folderId);
             
             return (IPlaceholderFolderLayout) mapFolderToFolderLayout.get(folder);
         }

         // Create the folder.
 ContainerPlaceholder folder = new ContainerPlaceholder(null);
         folder.setContainer(rootLayoutContainer);
         folder.setRealContainer(new ViewStack(rootLayoutContainer.page));
         folder.setID(folderId);
         addPart(folder, folderId, relationship, ratio, refId);

         // Create a wrapper.
 IPlaceholderFolderLayout layout = new PlaceholderFolderLayout(this, folder);
         
         mapFolderToFolderLayout.put(folder,layout);
         
         return layout;
     }

     /**
      * Create a new <code>LayoutPart</code>.
      *
      * @param partID the id of the part to create.
      * @return the <code>LayoutPart</code>, or <code>null</code> if it should not be
      * created because of activity filtering.
      * @throws PartInitException thrown if there is a problem creating the part.
      */
     private LayoutPart createView(String partID) throws PartInitException {
         if (partID.equals(ID_EDITOR_AREA)) {
             return editorFolder;
         }
         IViewDescriptor viewDescriptor = viewFactory.getViewRegistry()
                 .find(ViewFactory.extractPrimaryId(partID));
         if (WorkbenchActivityHelper.filterItem(viewDescriptor)) {
             return null;
         }
         return LayoutHelper.createView(getViewFactory(), partID);
     }

     /**
      * @return the action set list for the page. This is <code>List</code> of
      * <code>String</code>s.
      */
     public ArrayList getActionSets() {
         return actionSets;
     }

     /* (non-Javadoc)
      * @see org.eclipse.ui.IPageLayout#getDescriptor()
      */
     public IPerspectiveDescriptor getDescriptor() {
         return descriptor;
     }

     /**
      * @return an identifier for the editor area. The editor area is
      * automatically added to each layout before any other part. It should be
      * used as a reference part for other views.
      */
     public String getEditorArea() {
         return ID_EDITOR_AREA;
     }

     /* (non-Javadoc)
      * @see org.eclipse.ui.IPageLayout#getEditorReuseThreshold()
      */
     public int getEditorReuseThreshold() {
         return -1;
     }

     /**
      * @return <code>ArrayList</code>
      */
     public ArrayList getFastViews() {
         return fastViews;
     }

     /**
      * @return the folder part containing the given view ID or <code>null</code>
      * if none (i.e. part of the page layout instead of a folder layout).
      */
     private ViewStack getFolderPart(String viewId) {
         return (ViewStack) mapIDtoFolder.get(viewId);
     }

     /**
      * @return the new wizard shortcuts associated with the page. This is a <code>List</code> of
      * <code>String</code>s.
      */
     public ArrayList getNewWizardShortcuts() {
         return newWizardShortcuts;
     }

     /**
      * @return the part sash container const for a layout value.
      */
     private int getPartSashConst(int nRelationship) {
         return nRelationship;
     }

     /**
      * @return the perspective shortcuts associated with the page. This is a <code>List</code> of
      * <code>String</code>s.
      */
     public ArrayList getPerspectiveShortcuts() {
         return perspectiveShortcuts;
     }

     /**
      * @return the part for a given ID.
      */
     /*package*/
     LayoutPart getRefPart(String partID) {
         return (LayoutPart) mapIDtoPart.get(partID);
     }

     /**
      * @return the top level layout container.
      */
     public ViewSashContainer getRootLayoutContainer() {
         return rootLayoutContainer;
     }

     /**
      * @return the ids of the parts to list in the Show In... prompter. This is
      * a <code>List</code> of <code>String</code>s.
      */
     public ArrayList getShowInPartIds() {
         return showInPartIds;
     }

     /**
      * @return the show view shortcuts associated with the page. This is a <code>List</code> of
      * <code>String</code>s.
      */
     public ArrayList getShowViewShortcuts() {
         return showViewShortcuts;
     }

     /**
      * @return the <code>ViewFactory</code> for this <code>PageLayout</code>.
      * @since 3.0
      */
     /* package */
     ViewFactory getViewFactory() {
         return viewFactory;
     }

     /* (non-Javadoc)
      * @see org.eclipse.ui.IPageLayout#isEditorAreaVisible()
      */
     public boolean isEditorAreaVisible() {
         return editorVisible;
     }

     /**
      * Trim the ratio so that direct manipulation of parts is easy.
      *
      * @param in the initial ratio.
      * @return the normalized ratio.
      */
     private float normalizeRatio(float in) {
         if (in < RATIO_MIN) {
             in = RATIO_MIN;
         }
         if (in > RATIO_MAX) {
             in = RATIO_MAX;
         }
         return in;
     }

     /**
      * Prefill the layout with required parts.
      */
     private void prefill() {
         addEditorArea();

         // Add default action sets.
 ActionSetRegistry reg = WorkbenchPlugin.getDefault()
                 .getActionSetRegistry();
         IActionSetDescriptor[] array = reg.getActionSets();
         int count = array.length;
         for (int nX = 0; nX < count; nX++) {
             IActionSetDescriptor desc = array[nX];
             if (desc.isInitiallyVisible()) {
                 addActionSet(desc.getId());
             }
         }
     }

     /* (non-Javadoc)
      * @see org.eclipse.ui.IPageLayout#setEditorAreaVisible(boolean)
      */
     public void setEditorAreaVisible(boolean showEditorArea) {
         editorVisible = showEditorArea;
     }

     /* (non-Javadoc)
      * @see org.eclipse.ui.IPageLayout#setEditorReuseThreshold(int)
      */
     public void setEditorReuseThreshold(int openEditors) {
         //no-op
 }

     /* (non-Javadoc)
      * @see org.eclipse.ui.IPageLayout#setFixed(boolean)
      */
     public void setFixed(boolean fixed) {
         this.fixed = fixed;
     }

     /* (non-Javadoc)
      * @see org.eclipse.ui.IPageLayout#getFixed()
      */
     public boolean isFixed() {
         return fixed;
     }

     /**
      * Map the folder part containing the given view ID.
      *
      * @param viewId the part ID.
      * @param container the <code>ContainerPlaceholder</code>.
      */
     /*package*/
     void setFolderPart(String viewId, ContainerPlaceholder container) {
         LayoutPart tabFolder = container.getRealContainer();
         mapIDtoFolder.put(viewId, tabFolder);
     }

     /**
      * Map the folder part containing the given view ID.
      *
      * @param viewId the part ID.
      * @param folder the <code>ViewStack</code>.
      */
     /*package*/
     void setFolderPart(String viewId, ViewStack folder) {
         mapIDtoFolder.put(viewId, folder);
     }

     /**
      * Map an ID to a part.
      *
      * @param partId the part ID.
      * @param part the <code>LayoutPart</code>.
      */
     /*package*/
     void setRefPart(String partID, LayoutPart part) {
         mapIDtoPart.put(partID, part);
     }

     // stackPart(Layoutpart, String, String) added by dan_rubel@instantiations.com
 /**
      * Stack a part on top of another.
      *
      * @param newPart the new part.
      * @param viewId the view ID.
      * @param refId the reference ID.
      */
     private void stackPart(LayoutPart newPart, String viewId, String refId) {
         setRefPart(viewId, newPart);
         // force creation of the view layout rec
 getViewLayoutRec(viewId, true);

         // If ref part is in a folder than just add the
 // new view to that folder.
 ViewStack folder = getFolderPart(refId);
         if (folder != null) {
             folder.add(newPart);
             setFolderPart(viewId, folder);
             return;
         }

         // If the ref part is in the page layout then create
 // a new folder and add the new view.
 LayoutPart refPart = getRefPart(refId);
         if (refPart != null && (refPart instanceof PartPane || refPart instanceof PartPlaceholder)) {
             ViewStack newFolder = new ViewStack(rootLayoutContainer.page);
             rootLayoutContainer.replace(refPart, newFolder);
             newFolder.add(refPart);
             newFolder.add(newPart);
             setFolderPart(refId, newFolder);
             setFolderPart(viewId, newFolder);
             return;
         }

         // If ref part is not found then just do add.
 WorkbenchPlugin.log(NLS.bind(WorkbenchMessages.PageLayout_missingRefPart, refId ));
         rootLayoutContainer.add(newPart);
     }

     // stackPlaceholder(String, String) added by dan_rubel@instantiations.com
 /**
      * Stack a placeholder on top of another.
      *
      * @param viewId the view ID.
      * @param refId the reference ID.
      */
     public void stackPlaceholder(String viewId, String refId) {
         if (checkPartInLayout(viewId)) {
             return;
         }

         // Create the placeholder.
 PartPlaceholder newPart = new PartPlaceholder(viewId);

         LayoutPart refPart = getRefPart(refId);
         if (refPart != null) {
             newPart.setContainer(refPart.getContainer());
         }

         stackPart(newPart, viewId, refId);
     }

     // stackView(String, String) modified by dan_rubel@instantiations.com
 /**
      * Stack one view on top of another.
      *
      * @param viewId the view ID.
      * @param refId the reference ID.
      */
     public void stackView(String viewId, String refId) {
         if (checkPartInLayout(viewId)) {
             return;
         }

         // Create the new part.
 try {
             LayoutPart newPart = createView(viewId);
             if (newPart == null) {
                 stackPlaceholder(viewId, refId);
                 LayoutHelper.addViewActivator(this, viewId);
             } else {
                 stackPart(newPart, viewId, refId);
             }
         } catch (PartInitException e) {
             WorkbenchPlugin.log(getClass(), "stackView", e); //$NON-NLS-1$
 }
     }

     /**
      * Converts SWT position constants into layout position constants.
      *
      * @param swtConstant one of SWT.TOP, SWT.BOTTOM, SWT.LEFT, or SWT.RIGHT
      * @return one of IPageLayout.TOP, IPageLayout.BOTTOM, IPageLayout.LEFT, IPageLayout.RIGHT, or -1 indicating an
      * invalid input
      *
      * @since 3.0
      */
     public static int swtConstantToLayoutPosition(int swtConstant) {
         switch (swtConstant) {
         case SWT.TOP:
             return IPageLayout.TOP;
         case SWT.BOTTOM:
             return IPageLayout.BOTTOM;
         case SWT.RIGHT:
             return IPageLayout.RIGHT;
         case SWT.LEFT:
             return IPageLayout.LEFT;
         }

         return -1;
     }

     /* (non-Javadoc)
      * @see org.eclipse.ui.IPageLayout#addStandaloneView(java.lang.String, boolean, int, float, java.lang.String)
      * @since 3.0
      */
     public void addStandaloneView(String viewId, boolean showTitle,
             int relationship, float ratio, String refId) {
         addView(viewId, relationship, ratio, refId, false, true, showTitle);
         ViewLayoutRec rec = getViewLayoutRec(viewId, true);
         rec.isStandalone = true;
         rec.showTitle = showTitle;
     }
     
     /* (non-Javadoc)
      * @see org.eclipse.ui.IPageLayout#addStandaloneViewPlaceholder(java.lang.String, int, float, java.lang.String, boolean)
      */
     public void addStandaloneViewPlaceholder(String viewId, int relationship,
             float ratio, String refId, boolean showTitle) {

         String stackId = viewId + ".standalonefolder"; //$NON-NLS-1$

         // Check to see if the view is already in the layout
 if (!checkValidPlaceholderId(viewId)) {
             return;
         }

         // Create the folder.
 ContainerPlaceholder folder = new ContainerPlaceholder(null);
         folder.setContainer(rootLayoutContainer);
         int appearance = PresentationFactoryUtil.ROLE_STANDALONE;
         if (!showTitle) {
             appearance = PresentationFactoryUtil.ROLE_STANDALONE_NOTITLE;
         }
         folder.setRealContainer(new ViewStack(rootLayoutContainer.page, true,
                 appearance, null));
         folder.setID(stackId);
         addPart(folder, stackId, relationship, ratio, refId);

         // Create a wrapper.
 PlaceholderFolderLayout placeHolder = new PlaceholderFolderLayout(this,
                 folder);

         // Add the standalone view immediately
 placeHolder.addPlaceholder(viewId);

         ViewLayoutRec rec = getViewLayoutRec(viewId, true);
         rec.isStandalone = true;
         rec.showTitle = showTitle;
     }


     /*
      * (non-Javadoc)
      *
      * @see org.eclipse.ui.IPageLayout#getViewLayout(java.lang.String)
      * @since 3.0
      */
     public IViewLayout getViewLayout(String viewId) {
         ViewLayoutRec rec = getViewLayoutRec(viewId, true);
         if (rec == null) {
             return null;
         }
         return new ViewLayout(this, rec);
     }

     /**
      * @since 3.0
      */
     public Map getIDtoViewLayoutRecMap() {
         return mapIDtoViewLayoutRec;
     }

     /**
      * Removes any existing placeholder with the given id.
      *
      * @param id the id for the placeholder
      * @since 3.1
      */
     public void removePlaceholder(String id) {
         LayoutPart part = getRefPart(id);
         if (part instanceof PartPlaceholder) {
             ViewStack stack = getFolderPart(id);
             if (stack != null) {
                 stack.remove(part);
             }
             else {
                 rootLayoutContainer.remove(part);
             }
             mapIDtoPart.remove(id);
             mapIDtoFolder.remove(id);
             mapIDtoViewLayoutRec.remove(id);
         }
     }
     
     /* (non-Javadoc)
      * @see org.eclipse.ui.IPageLayout#getFolderForView(java.lang.String)
      */
     public IPlaceholderFolderLayout getFolderForView(String viewId)
     {
         if (!mapIDtoFolder.containsKey(viewId))
             return null;
                 
         ViewStack folder = (ViewStack) mapIDtoFolder.get(viewId);
         IPlaceholderFolderLayout layout = null;
         if (!mapFolderToFolderLayout.containsKey(folder))
         {
             layout = new FolderLayout(this, folder, viewFactory);
             mapFolderToFolderLayout.put(folder, layout);
         }
         else
         {
             layout = (IPlaceholderFolderLayout)mapFolderToFolderLayout.get(folder);
         }
         return layout;
     }
 }

